package com.example.forum.services.impl;

import com.example.forum.common.AppResult;
import com.example.forum.common.ResultCode;
import com.example.forum.config.RegexUtil;
import com.example.forum.dao.UserMapper;
import com.example.forum.exception.ApplicationException;
import com.example.forum.model.Board;
import com.example.forum.model.User;
import com.example.forum.services.IUserService;
import com.example.forum.utils.MD5Util;
import com.example.forum.utils.StringUtil;
import com.example.forum.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;

@Slf4j
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;
    @Override
    public void createNormalUser(User user) {
        //非空检验
        if(null==user|| StringUtil.isEmpty(user.getUsername())
        || StringUtil.isEmpty(user.getNickname()) || StringUtil.isEmpty(user.getPassword())
        || StringUtil.isEmpty(user.getSalt())) {
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.getMessage());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //按用户名来查询用户信息
        User existUser = userMapper.selectByUserName(user.getUsername());
        //判断用户是否存在
        if(null!=existUser){
            log.warn(ResultCode.AILED_USER_EXISTS.getMessage());
            // log.warn(ResultCode.AILED_USER_EXISTS.toString); 这样会将错误码一起打印出来
            throw new ApplicationException(AppResult.failed(ResultCode.AILED_USER_EXISTS));
        }

        //新增用户流程,设置默认值
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        //当前日期
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);

        //写入数据库
        int row = userMapper.insertSelective(user);
        if(row!=1){
            //表示没有插入成功
            log.error(ResultCode.FAILED_CREATE.getMessage());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        log.info("新增用户成功! username = {}",user.getUsername()+" .");
    }

    @Override
    public User selectByUserName(String username) {
        //非空校验
        if(StringUtil.isEmpty(username)){
            log.warn("输入的用户名为null");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //返回查询结果
        return userMapper.selectByUserName(username);
    }

    @Override
    public User login(String username, String password) {
        //非空校验
        if(StringUtil.isEmpty(username) || StringUtil.isEmpty(password)){
            log.warn("输入的参数为空!登录失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }

        //按照用户名查询用户信息
        User user = selectByUserName(username);

        //查询结果做非空校验
        if(user==null){
            log.warn("找不到对应用户,登录失败! username = {}",username);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }

        //根据查询信息来比对密码
        String salt = user.getSalt();
        String encryptPassword = MD5Util.md5Salt(password,salt);
        if(!encryptPassword.equals(user.getPassword())){
            log.error("用户名或密码输入错误!登录失败! username = {}",username);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
        //登录成功,返回用户信息
        log.info("当前用户登录成功! username = {}",username);
        return user;
    }

    @Override
    public User selectById(Long id) {
        //1.非空校验
        if(null==id){
            log.warn("传入的id为空!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //获得User对象
        User user = userMapper.selectByPrimaryKey(id);
        //返回
        return user;
    }

    @Override
    public void addOneArticleCountById(Long id) {
        if(null==id || id<=0){
            log.warn("传入的要修改的用户id有误! id = {}",id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if(null==user){
            log.error("没有找到该用户! id={}",id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXIST));
        }
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()+1);
        int row =userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.error("添加帖子失败! 受影响的行数不为1!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        if(null == id || id<=0){
            log.warn("被删除帖子的用户id传入为空!, id:{}",id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user = userMapper.selectByPrimaryKey(id);
        if(null==user){
            log.warn("当前用户不存在! id:{}",id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXIST));
        }
        User updateUser = new User();
        updateUser.setId(id);
        updateUser.setArticleCount(user.getArticleCount()-1);
        if(updateUser.getArticleCount()<0){
            updateUser.setArticleCount(0);
        }
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.error("删除用户帖子失败失败!,userId:{}",id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_ARTICLE_DELETE));
        }
    }

    @Override
    public void modifyInfo(User user) {
        if(null == user || user.getId() <= 0 || user.getId() == null){
            log.warn("没有传入正确的用户信息参数!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User existsUser = userMapper.selectByPrimaryKey(user.getId());
        if(null == existsUser || existsUser.getDeleteState() == 1){
            log.warn("当前用户不存在! userId:{}",user.getId());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //校验参数,来确定哪些要进行更新
        boolean checkAttr = false; //定义一个标志位,false用来表示校验没有通过(所有可以修改的参数都为空)
        //用来更新的对象,防止用户传入的对象设置了其他属性导致没有被校验就对信息进行了更改
        User updateUser = new User();
        updateUser.setId(user.getId());

        //校验用户名
        if(!StringUtil.isEmpty(user.getUsername())
                && !existsUser.getUsername().equals(user.getUsername())){
            // 需要更新用户名(登录名)时，进行唯一性的校验
            User checkUser = userMapper.selectByUserName(user.getUsername());
            if(checkUser!=null){
                log.warn("当前用户名已存在! userName:{}",user.getUsername());
                throw new ApplicationException(AppResult.failed(ResultCode.AILED_USER_EXISTS));
            }
            //可以进行修改
            updateUser.setUsername(user.getUsername());
            checkAttr = true;
        }

        //校验昵称
        if(!StringUtil.isEmpty(user.getNickname())
                && !user.getNickname().equals(existsUser.getNickname())){
            updateUser.setNickname(user.getNickname());
            checkAttr = true;
        }

        //校验性别
        if(user.getGender()!=null
                && !user.getGender().equals(existsUser.getGender())){
            updateUser.setGender(user.getGender());
            //性别设置要合法
            if(updateUser.getGender()>2 || updateUser.getGender()<0){
                updateUser.setGender((byte) 2);
            }
            checkAttr = true;
        }

        //检验邮箱
        if(!StringUtil.isEmpty(user.getEmail())
                && !user.getEmail().equals(existsUser.getEmail())){
            //检验邮箱是否合法
            if(!RegexUtil.checkMail(user.getEmail())){
                log.warn("邮箱格式输入不正确! email:{}",user.getEmail());
                throw new ApplicationException(AppResult.failed(ResultCode.EMAIL_FORMAT_ERROR));
            }
            updateUser.setEmail(user.getEmail());
            checkAttr = true;
        }

        //检验电话号码
        if(!StringUtil.isEmpty(user.getPhoneNum())
                && !user.getPhoneNum().equals(existsUser.getPhoneNum())){
            //检验手机号是否合法
            if(!RegexUtil.checkMobile(user.getPhoneNum())){
                log.warn("邮箱格式输入不正确! email:{}",user.getEmail());
                throw new ApplicationException(AppResult.failed(ResultCode.PHONE_FORMAT_ERROR));
            }
            updateUser.setPhoneNum(user.getPhoneNum());
            checkAttr = true;
        }

        //检验个人简介
        if(!StringUtil.isEmpty(user.getRemark())
                && !user.getRemark().equals(existsUser.getRemark())){
            updateUser.setRemark(user.getRemark());
            checkAttr = true;
        }

        //判断是否能进行更新
        if(checkAttr==false){
            log.warn("信息没有进行修改!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_INFO_MODIFY));
        }

        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.error("更新用户信息失败!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_INFO_UPDATE));
        }
    }

    @Override
    public void modifyPassword(Long userId, String newPassword, String oldPassword) {
        //校验
        if(null==userId || userId<=0 || StringUtil.isEmpty(newPassword) || StringUtil.isEmpty(oldPassword)){
            log.warn("传入的参数不合法!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //查询要修改的用户信息
        User user = userMapper.selectByPrimaryKey(userId);
        if(null==user || user.getDeleteState()==1){
            log.warn("该用户不存在! userId:{}",userId);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //校验旧密码是否正确
        //老密码进行加密
        String oldEncryptPassword = MD5Util.md5Salt(oldPassword,user.getSalt());
        //比较
        if(!oldEncryptPassword.equals(user.getPassword())){
            log.warn("旧密码输入错误");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_OLD_PASSWORD));
        }
        //旧密码输入正确之后,判断密码是否至少有六位
        if(!RegexUtil.checkPassword(newPassword)){
            log.warn("新设置的密码没有六位!安全系数过低");
            throw new ApplicationException(AppResult.failed(ResultCode.PASSWORD_NOT_SAFE));
        }

        //生成新盐
        String salt = UUIDUtil.UUID_32();
        String newEncryptPassword = MD5Util.md5Salt(newPassword,salt);

        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setSalt(salt);
        updateUser.setPassword(newEncryptPassword);
        updateUser.setUpdateTime(new Date());
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.error("更新用户密码失败!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_UPDATE_PASSWORD));
        }
    }

    @Override
    public void modifyAvatarUrl(Long userId, String avatarUrl) {
        //检验
        if(null == userId || userId<=0 || StringUtil.isEmpty(avatarUrl)){
            log.warn("用于修改头像的参数不合法!");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //查询要修改的用户信息
        User user = userMapper.selectByPrimaryKey(userId);
        if(null==user || user.getDeleteState()==1){
            log.warn("该用户不存在! userId:{}",userId);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //存入数据库
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setAvatarUrl(avatarUrl);
        updateUser.setUpdateTime(new Date());
        userMapper.updateByPrimaryKeySelective(updateUser);
    }
}
